package com.yungu.swift.api.facade;

import com.alibaba.dubbo.config.annotation.Reference;
import com.github.miemiedev.mybatis.paginator.domain.PageList;
import com.yungu.swift.assets.driver.model.dto.DriverDto;
import com.yungu.swift.assets.driver.service.DriverService;
import com.yungu.swift.base.ResponseData;
import com.yungu.swift.base.model.api.ApiPageParam;
import com.yungu.swift.constants.CommonConstant;
import com.yungu.swift.lbs.model.DriverLocation;
import com.yungu.swift.lbs.service.LocationService;
import com.yungu.swift.order.model.dto.OrderDetailDto;
import com.yungu.swift.order.model.dto.OrderDto;
import com.yungu.swift.order.model.dto.OrderFareDto;
import com.yungu.swift.order.model.param.ApiOrderUuidParam;
import com.yungu.swift.order.model.param.CrosstownOrderParam;
import com.yungu.swift.order.model.vo.ApiDriverOrderVo;
import com.yungu.swift.order.model.vo.JsonOrderDetailVo;
import com.yungu.swift.order.model.vo.JsonOrderListVo;
import com.yungu.swift.order.model.vo.OrderEstimateVo;
import com.yungu.swift.order.service.OrderAssignService;
import com.yungu.swift.order.service.OrderFareService;
import com.yungu.swift.order.service.OrderJoinService;
import com.yungu.swift.order.service.OrderRiskControlService;
import com.yungu.swift.order.service.OrderService;
import com.yungu.swift.system.sys.model.dto.SysBusinessOrganizationDto;
import com.yungu.swift.system.sys.service.SysBusinessOrganizationService;
import com.yungu.swift.system.sys.service.SysCityService;
import com.yungu.swift.utils.MapUtils;
import com.yungu.swift.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.Map;

import static com.yungu.swift.order.model.enums.OrderErrorEnum.GRAB_ERROR_4017;

/**
 * Created by cuixiuyin on 2018/4/14.
 */
@Slf4j
@Component
public class DriverFacade {

    @Reference
    private DriverService driverService;
    @Reference
    private OrderService orderService;
    @Reference
    private OrderJoinService orderJoinService;
    @Reference
    private OrderAssignService orderAssignService;
    @Reference
    private OrderRiskControlService orderRiskControlService;
    @Reference
    private OrderFareService orderFareService;
    @Reference
    private LocationService locationService;
    @Reference
    private SysCityService sysCityService;
    @Reference
    private SysBusinessOrganizationService sysBusinessOrganizationService;

    /**
     * 司机抢单
     *
     * @param driverUuid
     * @param orderUuid
     * @return
     */
    public ResponseData<JsonOrderDetailVo> grab(String driverUuid, String orderUuid, String uploadText) {
        if (StringUtils.isEmpty(driverUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到用户ID");
        }
        if (StringUtils.isEmpty(orderUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "订单编号不能为空");
        }
        DriverDto driverDto = driverService.get(driverUuid).getData();
        if (driverDto == null) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到司机数据");
        }
        return orderAssignService.updGrab(orderUuid, driverDto, uploadText);
    }

    /**
     * 司机出发接乘客
     *
     * @param driverUuid
     * @param orderUuid
     * @return
     */
    public ResponseData<Boolean> pickUpPas(String driverUuid, String orderUuid, String uploadText) {
        if (StringUtils.isEmpty(driverUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到用户ID");
        }
        if (StringUtils.isEmpty(orderUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "订单编号不能为空");
        }
        return orderService.updPickUpPas(orderUuid, uploadText);
    }

    /**
     * 司机到达上车地点
     *
     * @param driverUuid
     * @param orderUuid
     * @return
     */
    public ResponseData<Boolean> depart(String driverUuid, String orderUuid, String uploadText) {
        if (StringUtils.isEmpty(driverUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到用户ID");
        }
        if (StringUtils.isEmpty(orderUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "订单编号不能为空");
        }
        return orderService.updDepart(orderUuid, uploadText);
    }

    /**
     * 司机接到乘客
     *
     * @param driverUuid
     * @param orderUuid
     * @return
     */
    public ResponseData<Boolean> geton(String driverUuid, String orderUuid, Double waitMile, String uploadText) {
        if (StringUtils.isEmpty(driverUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到用户ID");
        }
        if (StringUtils.isEmpty(orderUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "订单编号不能为空");
        }
        return orderService.updGeton(orderUuid, waitMile, uploadText);
    }

    /**
     * 司机到达目的地
     */
    public ResponseData<Boolean> arrive(String driverUuid, String orderUuid, Double tripDistance, int businessType,
                                        String destAddress, String destDetailAddress, String destCity, Double destLng,
                                        Double destLat, String uploadText, String tripRecording) {
        if (StringUtils.isEmpty(driverUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到用户ID");
        }
        // 租车记录目的地信息
        OrderDetailDto destination = new OrderDetailDto();
        destination.setDestAddress(destAddress);
        destination.setDestDetailAddress(destDetailAddress);
        destination.setDestCity(destCity);
        destination.setDestLng(destLng);
        destination.setDestLat(destLat);
        destination.setDestCityUuid(sysCityService.getCityUuidByName(destCity).getData());
        //if (CommonConstant.BUSINESS_TYPE_TAXI == businessType) {
        //    return orderService.taxiUpdArrive(orderUuid, uploadText);
        //}
        //非出租车情况
        return orderService.updArrive(orderUuid, tripDistance, tripRecording, destination, uploadText);
    }

    /**
     * 快车和专车确认费用
     *
     * @param driverUuid
     * @param orderUuid
     * @return
     */
    public ResponseData<Boolean> confirmFare(String driverUuid, String orderUuid, Integer highwayFare, Integer roadBridgeFare, Integer otherFare, String uploadText) {
        if (StringUtils.isEmpty(driverUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到用户ID");
        }
        if (StringUtils.isEmpty(orderUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "订单编号不能为空");
        }
        //当存在高速费等其他费用时，存入订单费用表
        if (highwayFare != null || roadBridgeFare != null || otherFare != null) {
            OrderFareDto orderFareDto = new OrderFareDto();
            orderFareDto.setHighwayFare(highwayFare == null ? 0 : highwayFare);
            orderFareDto.setRoadBridgeFare(roadBridgeFare == null ? 0 : roadBridgeFare);
            orderFareDto.setOtherFare(otherFare == null ? 0 : otherFare);
            orderFareDto.setOrderUuid(orderUuid);
            orderFareService.saveAdditionalFare(orderFareDto);
        }

        return orderService.confirmFare(orderUuid, uploadText);
    }

    /**
     * 首页获取订单状态
     *
     * @param driverUuid
     * @param typeModule 业务类型
     * @return
     */
    public ResponseData<Map<String, Object>> status(String driverUuid, int typeModule) {
        if (StringUtils.isEmpty(driverUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取用户Id出错");
        }
        return orderService.getDriOrderStatus(driverUuid, typeModule);
    }

    /**
     * 司机获取订单列表
     *
     * @param driverUuid
     * @param nowPage
     * @return
     */
    public ResponseData<PageList<JsonOrderListVo>> list(String driverUuid, Integer nowPage) {
        if (StringUtils.isEmpty(driverUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到用户ID");
        }
        //根据实际接单司机actualDriverUuid字段查询订单列表，按出发时间降续排列
        Map<String, Object> map = MapUtils.build(2);
        map.put("actualDriverUuid", driverUuid);
        return orderService.queryPageList(map, new ApiPageParam(nowPage));
    }

    /**
     * 新获取司机订单列表
     *
     * @param driUuid
     * @param type
     * @param businessType
     * @param startDate
     * @param endDate
     * @param apiPageParam
     * @return
     */
    public ResponseData<ApiDriverOrderVo> listNew(String driUuid, Integer type, Integer businessType, Date startDate,
                                                  Date endDate, ApiPageParam apiPageParam) {
        // 1. 统计订单数据
        ApiDriverOrderVo driverOrderVo = orderService.statisticDriverOrder(driUuid, type, startDate, endDate).getData();
        if (driverOrderVo == null) {
            driverOrderVo = new ApiDriverOrderVo();
        }
        // 专/快/出租
        if (CommonConstant.BUSINESS_TYPE_POOL != businessType) {
            Map<String, Object> map = MapUtils.build(2);
            map.put("actualDriverUuid", driUuid);
            map.put("type", type);
            map.put("startDate", startDate);
            map.put("endDate", endDate);
            PageList<JsonOrderListVo> data = orderService.queryPageList(map, apiPageParam).getData();
            //获取订单金额，并计算抽成后的金额
            BigDecimal amount = driverOrderVo.getOrderFareSum();
            //计算扣除抽成比例后的金额
            //获取平台抽成比例
            SysBusinessOrganizationDto platform = sysBusinessOrganizationService.getPlatformCommission(driUuid, businessType).getData();
            if (platform != null && platform.getCommission() != null && platform.getCommission() > 0) {
                if (platform.getCommissionType() == 1) {//=1 按照百分比抽成
                    amount = amount.subtract(driverOrderVo.getOrderFareSum().multiply(BigDecimal.valueOf(platform.getCommission()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP))).setScale(2, RoundingMode.HALF_UP);
                    for (int i = 0; i < data.size(); i++) {
                        JsonOrderListVo jsonOrderListVo = data.get(i);
                        BigDecimal orderFare =  jsonOrderListVo.getOrderFare();
                        if(jsonOrderListVo.getTotalFare() != null) {
                            BigDecimal totalFare = BigDecimal.valueOf(jsonOrderListVo.getTotalFare());
                            totalFare = totalFare.subtract(orderFare.multiply(BigDecimal.valueOf(platform.getCommission()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP))).setScale(2, RoundingMode.HALF_UP);
                            jsonOrderListVo.setTotalFare(totalFare.doubleValue());
                        }
                    }
                } else if (platform.getCommissionType() == 2) {//=2 抽成固定金额
                    amount = amount.subtract(BigDecimal.valueOf(platform.getCommission()));
                    for (int i = 0; i < data.size(); i++) {
                        JsonOrderListVo jsonOrderListVo = data.get(i);
                        if(jsonOrderListVo.getTotalFare() != null) {
                            BigDecimal totalFare = BigDecimal.valueOf(jsonOrderListVo.getTotalFare());
                            totalFare = totalFare.subtract(BigDecimal.valueOf(platform.getCommission()));
                            jsonOrderListVo.setTotalFare(totalFare.doubleValue());
                        }
                    }
                }
            }
            //获取代理抽成比例
            SysBusinessOrganizationDto agency = sysBusinessOrganizationService.getAgencyCommission(driUuid, businessType).getData();
            if (agency != null && agency.getCommission() != null && agency.getCommission() > 0) {
                if (agency.getCommissionType() == 1) {//=1 按照百分比抽成
                    amount = amount.subtract(driverOrderVo.getOrderFareSum().multiply(BigDecimal.valueOf(agency.getCommission()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP))).setScale(2, RoundingMode.HALF_UP);
                    for (int i = 0; i < data.size(); i++) {
                        JsonOrderListVo jsonOrderListVo = data.get(i);
                        BigDecimal orderFare =  jsonOrderListVo.getOrderFare();
                        if(jsonOrderListVo.getTotalFare() != null) {
                            BigDecimal totalFare = BigDecimal.valueOf(jsonOrderListVo.getTotalFare());
                            totalFare = totalFare.subtract(orderFare.multiply(BigDecimal.valueOf(agency.getCommission()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP))).setScale(2, RoundingMode.HALF_UP);
                            jsonOrderListVo.setTotalFare(totalFare.doubleValue());
                        }
                    }
                } else if (platform.getCommissionType() == 2) {//=2 抽成固定金额
                    amount = amount.subtract(BigDecimal.valueOf(agency.getCommission()));
                    for (int i = 0; i < data.size(); i++) {
                        JsonOrderListVo jsonOrderListVo = data.get(i);
                        if(jsonOrderListVo.getTotalFare() != null) {
                            BigDecimal totalFare = BigDecimal.valueOf(jsonOrderListVo.getTotalFare());
                            totalFare = totalFare.subtract(BigDecimal.valueOf(agency.getCommission()));
                            jsonOrderListVo.setTotalFare(totalFare.doubleValue());
                        }
                    }
                }
            }
            //获取公司抽成比例
            SysBusinessOrganizationDto company = sysBusinessOrganizationService.getCompanyCommission(driUuid, businessType).getData();
            if (company != null && company.getCommission() != null && company.getCommission() > 0) {
                if (company.getCommissionType() == 1) {//=1 按照百分比抽成
                    amount = amount.subtract(driverOrderVo.getOrderFareSum().multiply(BigDecimal.valueOf(company.getCommission()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP))).setScale(2, RoundingMode.HALF_UP);
                    for (int i = 0; i < data.size(); i++) {
                        JsonOrderListVo jsonOrderListVo = data.get(i);
                        BigDecimal orderFare =  jsonOrderListVo.getOrderFare();
                        if(jsonOrderListVo.getTotalFare() != null) {
                            BigDecimal totalFare = BigDecimal.valueOf(jsonOrderListVo.getTotalFare());
                            totalFare = totalFare.subtract(orderFare.multiply(BigDecimal.valueOf(company.getCommission()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP))).setScale(2, RoundingMode.HALF_UP);
                            jsonOrderListVo.setTotalFare(totalFare.doubleValue());
                        }
                    }
                } else if (platform.getCommissionType() == 2) {//=2 抽成固定金额
                    amount = amount.subtract(BigDecimal.valueOf(company.getCommission()));
                    for (int i = 0; i < data.size(); i++) {
                        JsonOrderListVo jsonOrderListVo = data.get(i);
                        if(jsonOrderListVo.getTotalFare() != null) {
                            BigDecimal totalFare = BigDecimal.valueOf(jsonOrderListVo.getTotalFare());
                            totalFare = totalFare.subtract(BigDecimal.valueOf(company.getCommission()));
                            jsonOrderListVo.setTotalFare(totalFare.doubleValue());
                        }
                    }
                }
            }
            driverOrderVo.setOrderFareSum(amount);
            driverOrderVo.setPageList(data);
        }
        // 拼车
        if (CommonConstant.BUSINESS_TYPE_POOL == businessType) {
            CrosstownOrderParam crosstownOrderParam = new CrosstownOrderParam();
            crosstownOrderParam.setDriverUuid(driUuid);
            crosstownOrderParam.setStartDate(startDate);
            crosstownOrderParam.setEndDate(endDate);
            crosstownOrderParam.setNowPage(apiPageParam.getNowPage());
            crosstownOrderParam.setPageSize(10);
            driverOrderVo.setJoinPageList(orderJoinService.crosstownOrderListInfo(crosstownOrderParam, type).getData());
        }
        return ResponseData.buildSuccessResponse(driverOrderVo);
    }

    /**
     * 订单详情
     *
     * @param driverUuid
     * @param orderUuid
     * @return
     */
    public ResponseData<JsonOrderDetailVo> info(String driverUuid, String orderUuid) {
        if (StringUtils.isEmpty(driverUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到用户ID");
        }
        if (!StringUtils.isNotEmpty(orderUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "参数错误");
        }
        //判断是否有效订单（改派情况）
        if (!orderRiskControlService.isValidOrder(orderUuid, driverUuid).getData()) {
            return ResponseData.buildErrorResponse(GRAB_ERROR_4017.getCode(), GRAB_ERROR_4017.getMsg());
        }
        return orderService.getOrderDetail(orderUuid, driverUuid);
    }

    /**
     * 订单费用
     *
     * @param driverUuid
     * @param orderUuid
     * @param type
     * @return
     */
    public ResponseData<Map<String, Object>> orderFare(String driverUuid, String orderUuid,int type) {
        if (driverService.selInfo(driverUuid) == null) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取用户信息错误");
        }
        return orderFareService.getFareItems(orderUuid, null,type);
    }

    /**
     * 获取订单的时时价格和时间
     *
     * @return
     * @throws Exception
     */
    public ResponseData<OrderEstimateVo> getRealtimeFare(String appid, String orderUuid) throws Exception {
        Map<String, Object> map = MapUtils.build();
        map.put("orderUuid", orderUuid);
        OrderFareDto orderFareDto = orderFareService.get(map).getData();
        if (orderFareDto == null) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取订单有误");
        }
        //默认
        Double realDistance = 0d;
        map.put("lat", 0);
        map.put("lng", 0);
        DriverLocation driverPoint = locationService.findNewestOrderLocation(orderUuid, appid).getData();
        if (driverPoint != null) {
            realDistance = driverPoint.getMileage();
            map.put("lat", driverPoint.getCoordinate().getLat());
            map.put("lng", driverPoint.getCoordinate().getLng());
        }
        ApiOrderUuidParam orderUuidParam = new ApiOrderUuidParam();
        orderUuidParam.setAppid(appid);
        orderUuidParam.setOrderUuid(orderUuid);
        ResponseData<OrderEstimateVo> responseData = orderFareService.getRealtimeFare(orderUuidParam);
        if (!responseData.isSuccess() || responseData.getData() == null) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取最新价格失败");
        } else {
            //根据订单id获取订单信息
            ResponseData<OrderDto> orderDtoResponseData = orderService.get(orderUuid);
            if(!orderDtoResponseData.isSuccess() || orderDtoResponseData.getData() == null) {
                return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "未获取到订单信息");
            } else {
                OrderDto orderDto = orderDtoResponseData.getData();
                //计算代理抽成和公司抽成后的金额
                BigDecimal total = BigDecimal.valueOf(responseData.getData().getTotalFare());
                BigDecimal totals = total;
                //获取平台抽成比例
                SysBusinessOrganizationDto platform = sysBusinessOrganizationService.getPlatformCommission(orderDto.getActualDriverUuid(), orderDto.getTypeModule()).getData();
                if (platform != null && platform.getCommission() != null && platform.getCommission() > 0) {
                    if (platform.getCommissionType() == 1) {//=1 按照百分比抽成
                        total = total.subtract(totals.multiply(BigDecimal.valueOf(platform.getCommission()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP))).setScale(2, RoundingMode.HALF_UP);
                    } else if (platform.getCommissionType() == 2) {//=2 抽成固定金额
                        total = total.subtract(BigDecimal.valueOf(platform.getCommission()));
                    }
                }
                //获取代理抽成比例
                SysBusinessOrganizationDto agency = sysBusinessOrganizationService.getAgencyCommission(orderDto.getActualDriverUuid(), orderDto.getTypeModule()).getData();
                if (agency != null && agency.getCommission() != null && agency.getCommission() > 0) {
                    if (agency.getCommissionType() == 1) {//=1 按照百分比抽成
                        total = total.subtract(totals.multiply(BigDecimal.valueOf(agency.getCommission()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP))).setScale(2, RoundingMode.HALF_UP);
                    } else if (platform.getCommissionType() == 2) {//=2 抽成固定金额
                        total = total.subtract(BigDecimal.valueOf(agency.getCommission()));
                    }
                }
                //获取公司抽成比例
                SysBusinessOrganizationDto company = sysBusinessOrganizationService.getCompanyCommission(orderDto.getActualDriverUuid(), orderDto.getTypeModule()).getData();
                if (company != null && company.getCommission() != null && company.getCommission() > 0) {
                    if (company.getCommissionType() == 1) {//=1 按照百分比抽成
                        total = total.subtract(totals.multiply(BigDecimal.valueOf(company.getCommission()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP))).setScale(2, RoundingMode.HALF_UP);
                    } else if (platform.getCommissionType() == 2) {//=2 抽成固定金额
                        total = total.subtract(BigDecimal.valueOf(company.getCommission()));
                    }
                }
                responseData.getData().setTotalFare(total.doubleValue());
            }
        }
        return responseData;
    }

    public static void main(String[] args) {
        double aa = 10;
        BigDecimal amount = new BigDecimal(89.23);
        System.out.println(BigDecimal.valueOf(aa).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP).setScale(2, RoundingMode.HALF_UP));
        System.out.println(amount.multiply(BigDecimal.valueOf(10/100)));
        amount = amount.subtract(amount.multiply(BigDecimal.valueOf(aa).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP))).setScale(2, RoundingMode.HALF_UP);
        System.out.println(amount);
    }
}
